package com.gitee.slowcreator.http.config;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zxw
 * @date 2023/1/8 下午12:33
 */
public class HttpContextManager {

    private static final ThreadLocal<HttpContext> context = ThreadLocal.withInitial(() -> {

        HttpContext h = new HttpContext();
        return h.setTraceId(IdUtil.fastSimpleUUID())
                .setRequestTimeout(-1);
    });

    /**
     * 获取 HttpContext
     *
     * @return
     */
    public static HttpContext get() {

        return context.get();
    }

    public static void remove() {

        context.remove();
    }

    /**
     * 扩展参数
     * 因为这一部分会可能在进入http请求增强前调用（比如设置了json解析）
     * 如果和 context 放在一起就有可能出现用户设置完，代码报错了，没调用remove，导致内存泄漏
     * 或者http请求结束，调用了remove，导致用户后面如果要用又会出问题
     * 把扩展类单独拿出来 用户自己控制remove
     */
    public static class Extend {

        private static final ThreadLocal<Map<String, Object>> extendTl = ThreadLocal.withInitial(HashMap::new);

        /**
         * 添加/更新扩展参数
         *
         * @param key   扩展参数键
         * @param value 扩展参数值
         */
        public static void add(String key, Object value) {

            Map<String, Object> map = extendTl.get();
            map.put(key, value);
        }

        /**
         * 添加扩展参数 会遍历放入 不会用这个参数替换原本thread local上的参数
         *
         * @param params 扩展参数
         */
        public static void addMap(Map<String, Object> params) {

            if (CollectionUtil.isEmpty(params)) {
                return;
            }
            Map<String, Object> map = extendTl.get();
            map.putAll(params);
        }

        /**
         * 获取扩展参数
         *
         * @param key 扩展参数map中的key
         * @return
         */
        public static Object get(String key) {

            Map<String, Object> map = extendTl.get();
            return map.get(key);
        }

        /**
         * 获取整个扩展参数
         *
         * @return
         */
        public static Map<String, Object> get() {

            // 不允许获取后直接修改这里面的参数 避免用户获取后传入多线程操作这个参数
            return Collections.unmodifiableMap(extendTl.get());
        }

        /**
         * 使用后调用 避免内存泄漏
         */
        public static void remove() {

            extendTl.remove();
        }
    }
}
